package com.maserb.monitor.service.schoolStudent.impl;

import com.maserb.monitor.common.CreateTimeUtils;
import com.maserb.monitor.entity.JwOrgEntity;
import com.maserb.monitor.entity.UserEntity;
import com.maserb.monitor.entity.schoolOrg.SchoolUserOrgEntity;
import com.maserb.monitor.entity.schoolStudent.SchoolStudentEntity;
import com.maserb.monitor.entity.schoolStudent.SchoolStudentImportModel;
import com.maserb.monitor.entity.schoolStudent.SchoolStudentParentEntity;
import com.maserb.monitor.entity.schoolStudent.SchoolStudentParentImportModel;
import com.maserb.monitor.repository.schoolOrg.SchoolUserOrgRepository;
import com.maserb.monitor.repository.schoolStudent.SchoolStudentParentRepository;
import com.maserb.monitor.repository.schoolStudent.SchoolStudentRepository;
import com.maserb.monitor.repository.schoolStudent.StudentAchieveRepository;
import com.maserb.monitor.service.author_manage.UserService;
import com.maserb.monitor.service.base.impl.JpaSpecificationServiceImpl;
import com.maserb.monitor.service.jwEducation.JwOrgService;
import com.maserb.monitor.service.remote.EcCardService;
import com.maserb.monitor.service.schoolStudent.SchoolStudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SchoolStudentServiceImpl extends JpaSpecificationServiceImpl<SchoolStudentRepository,
        SchoolStudentRepository, SchoolStudentEntity, String>
        implements SchoolStudentService {


    @Autowired
    StudentAchieveRepository achieveRepository;

    @Autowired
    private JwOrgService orgService;

    @Autowired
    private UserService userService;

    @Autowired
    private EcCardService ecCardService;

    @Autowired
    private SchoolUserOrgRepository schoolUserOrgRepository;

    @Autowired
    private SchoolStudentParentRepository parentRepository;

    private Specification<SchoolStudentEntity> getSpecification(List<String> clazzIdList,String name, String orgId, String studentId, String schoolId, String sex) {
        return new Specification<SchoolStudentEntity>()  {
            @Override
            public Predicate toPredicate(Root<SchoolStudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<String> pathName = root.get("name");
                Path<String> pathOrgId = root.get("orgId");
                Path<String> pathStudentId = root.get("studentId");
                Path<String> pathSchoolId = root.get("schoolId");
                Path<String> pathSex = root.get("sex");
                Path<String> pathIsDel = root.get("isDel");
                ArrayList<Predicate> list = new ArrayList<Predicate>();
                if (!StringUtils.isEmptyOrWhitespace(name)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.like(pathName, "%" + name + "%")));
                }
                if (!StringUtils.isEmptyOrWhitespace(orgId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathOrgId, orgId)));
                }
                if (!StringUtils.isEmptyOrWhitespace(studentId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathStudentId, studentId)));
                }
                if (!StringUtils.isEmptyOrWhitespace(schoolId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathSchoolId, schoolId)));
                }
                if (!StringUtils.isEmptyOrWhitespace(sex)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathSex, sex)));
                }
                Expression<String> exp = root.<String>get("orgId");
                if(null!=clazzIdList && clazzIdList.size()>0){
                    list.add(exp.in(clazzIdList));
                }
                list.add(criteriaBuilder.and(criteriaBuilder.equal(pathIsDel, "0")));
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
    }

    @Override
    public Page<SchoolStudentEntity> findAll(Pageable pageable,String userId, String name, String orgId, String studentId, String schoolId, String sex) {
        List<String>clazzIdList = new ArrayList<String>();
        if(!StringUtils.isEmptyOrWhitespace(userId)){
            UserEntity user = userService.findOne(userId);
            schoolId = user.getOrgId();
            JwOrgEntity org = orgService.findOne(schoolId);
            if(org.getTreeLevel() < 1){
                schoolId = "";
            }
            if(!StringUtils.isEmptyOrWhitespace(orgId)){
                JwOrgEntity jwOrgEntity = orgService.findOne(orgId);
                if(jwOrgEntity.getTreeLevel()==1){
                    schoolId = orgId;
                    orgId="";
                }
            }
            List<JwOrgEntity>clazzList = orgService.findByUser(user);
            for(JwOrgEntity orgEntity:clazzList){
                clazzIdList.add(orgEntity.getId());
            }
        }
        return this.findAll(getSpecification(clazzIdList,name,orgId,studentId,schoolId,sex), pageable);
    }

    @Override
    public List<SchoolStudentEntity> findAll(String userId,String name, String orgId, String studentId, String schoolId, String sex) {
        List<String>clazzIdList = new ArrayList<String>();
        if(!StringUtils.isEmptyOrWhitespace(userId)){
            UserEntity user = userService.findOne(userId);
            schoolId = user.getOrgId();
            JwOrgEntity org = orgService.findOne(schoolId);
            if(org.getTreeLevel() < 1){
                schoolId = "";
            }
            if(!StringUtils.isEmptyOrWhitespace(orgId)){
                JwOrgEntity jwOrgEntity = orgService.findOne(orgId);
                if(jwOrgEntity.getTreeLevel()==1){
                    schoolId = orgId;
                    orgId="";
                }
            }
            List<JwOrgEntity>clazzList = orgService.findByUser(user);
            for(JwOrgEntity orgEntity:clazzList){
                clazzIdList.add(orgEntity.getId());
            }
        }
        return new ArrayList(this.findAll(getSpecification(clazzIdList,name,orgId,studentId,schoolId,sex),new PageRequest(0,1000)).getContent());
    }

    @Override
    public Integer countByClass(String classId) {
        return this.repository.countByOrgId(classId);
    }

    @Override
    public List<SchoolStudentEntity> findByClazzId(String clazzId) {
        return this.repository.findAllByOrgIdOrderByNameDesc(clazzId);
    }

    @Override
    public List<SchoolStudentEntity> studentListByNameOrId(String clazzId, String nameOrId) {
        return this.repository.findAllByNameOrId(clazzId, nameOrId);
    }

    @Override
    public List<SchoolStudentEntity> findByClazzIdWithScore(String clazzId) {
        List<SchoolStudentEntity> studentList = this.repository.findAllByOrgIdOrderByNameDesc(clazzId);

        for(SchoolStudentEntity student : studentList) {
            if(student != null) {
                getStudentScore(student);
            }
        }

        return studentList;
    }

    @Override
    public List<SchoolStudentEntity> findByUser(UserEntity user) {
        List<JwOrgEntity>clazzList = orgService.findByUser(user);
        List<SchoolStudentEntity>studentList = new ArrayList<SchoolStudentEntity>();
        for(JwOrgEntity orgEntity:clazzList){
            List<SchoolStudentEntity>list = this.repository.findAllByOrgIdOrderByNameDesc(orgEntity.getId());
            studentList.addAll(list);
        }
        return studentList;
    }


    @Override
    public SchoolStudentEntity getStudentScore(SchoolStudentEntity student) {
        //当前学期的平均分  学生每次考试都写入当前班级  变班级后（升级）上学年的成绩不计入当前平均分
        Double examScore = achieveRepository.queryAvgScoreByStudent(student.getId(), student.getOrgId());
        if(examScore==null){
            examScore = 0d;
        }
        if(student.getConductScore() == null) {
            student.setConductScore(0);
        }
        Double evaluationScore = (examScore + student.getConductScore()) / 2;

        student.setExamScore(examScore);
        student.setEvaluationScore(evaluationScore);

        return student;
    }

    @Override
    public List<SchoolStudentEntity> findByParent(SchoolStudentParentEntity parent) {
        return this.repository.findByParent(parent);
    }

    @Override
    public List<JwOrgEntity> getOrgListByParent(SchoolStudentParentEntity parent) {
       /* List<String>*/
        return this.repository.getOrgListByParent(parent);
    }

    @Override
    public SchoolStudentEntity findByStudentNo(String studentNo) {
        return this.repository.findFirstByStudentId(studentNo);
    }

    @Override
    public Page<SchoolStudentEntity> findAllByUser(Pageable pageable, String userId, String clazzId, String name, String studentId) {
        List<String>clazzIdList = new ArrayList<String>();
        if(!StringUtils.isEmptyOrWhitespace(userId)){
            UserEntity user = userService.findOne(userId);
            List<JwOrgEntity>clazzList = orgService.findByUser(user);
            for(JwOrgEntity orgEntity:clazzList){
                clazzIdList.add(orgEntity.getId());
            }
        }
        return this.findAll(getSpecificationByUser(clazzIdList,clazzId,name,studentId),pageable);
    }

    @Override
    public void save(List<SchoolStudentEntity> list, String orgId, String clazzId, String userId) {
        for(SchoolStudentEntity entity:list){
            if(StringUtils.isEmptyOrWhitespace(entity.getStudentId())) {
                continue;
            }
            entity.setCreateUser(userId);
            entity.setMaster(userService.findOne(userId));
            entity.setIsDel("0");
            entity.setCreateTime(CreateTimeUtils.getCreateTime());
            if(!StringUtils.isEmptyOrWhitespace(clazzId)){
                JwOrgEntity orgEntity = orgService.findOne(clazzId);
                entity.setOrgId(clazzId);
                entity.setOrgName(orgEntity.getName());
                entity.setDid(orgEntity.getDid());

                if(orgEntity.getParent() != null) {
                    entity.setSchoolId(orgEntity.getParent().getId());
                    entity.setSchoolName(orgEntity.getParent().getName());
                }
            }
            if(StringUtils.isEmptyOrWhitespace(entity.getSchoolId()) && !StringUtils.isEmptyOrWhitespace(orgId)){
                JwOrgEntity orgEntity = orgService.findOne(orgId);
                entity.setSchoolId(orgId);
                entity.setSchoolName(orgEntity.getName());
            }
            if(entity.getSchoolId().equals("2c90ee426565d98e016565db352f0000")) {
                //崇庆中学
                Long cid = ecCardService.doAddPerson(entity);
                if(null!=cid){
                    entity.setCid(cid);
                }
            }

            if(!StringUtils.isEmptyOrWhitespace(entity.getPhoneNumber())) {
                saveParent(entity);
            }
            String imageUrl = entity.getSchoolId()+"\\"+entity.getStudentId()+".jpg";
            imageUrl=imageUrl.replaceAll("\\\\", "/");
            entity.setImage(imageUrl);
            entity.setConductScore(100);
            this.save(entity);


        }
    }

    public void saveTeacher(List<SchoolStudentImportModel> list) {
        for(SchoolStudentImportModel model : list) {
            UserEntity teacher = userService.findFirstByName(model.getName());
            if(teacher != null) {
                //数据库已存在
                teacher.setDid(model.getDid());
                teacher.setCardNumber(model.getCardNumber());
                teacher.setCid(model.getCid());
                teacher.setSex("1");
                teacher.setTeacherId(model.getStudentId());

                userService.save(teacher);
            }
        }
    }

    @Override
    public void saveParent(List<SchoolStudentParentImportModel> list) {
        for(SchoolStudentParentImportModel model : list) {
            if(!StringUtils.isEmpty(model.getPhoneNumber())) {
                SchoolStudentEntity student = repository.findFirstByCardNumber(model.getCardNumber());
                saveParent(student);
            }
        }
    }

    @Override
    public void initParent() {
        List<SchoolStudentEntity> studentList = repository.findAllByParentIsNull();
        for(SchoolStudentEntity student : studentList) {
            SchoolStudentParentEntity parent = parentRepository.findFirstByRealName(student.getName() + "家长");
            if(parent != null) {
                student.setParent(parent);
                repository.save(student);
            }
        }
    }

    private void saveParent(SchoolStudentEntity student) {
        if(student != null) {
            SchoolStudentParentEntity parent = new SchoolStudentParentEntity();
            parent.setUserName(student.getPhoneNumber());
            parent.setPhoneNumber(student.getPhoneNumber());
            parent.setPassword("123456");
            parent.setIsDel("0");
            parent.setRealName(student.getName() + "家长");
            parentRepository.save(parent);
            student.setParent(parent);
            student.setSex(student.getSex());
            student.setConductScore(100);
            repository.save(student);
        }
    }

    @Override
    public List<SchoolStudentEntity> findByClazzName(String clazzName) {
        return repository.findByOrgNameLike(clazzName);
    }

    @Override
    public void save(List<SchoolStudentImportModel> list) {
        Map<String, JwOrgEntity> clazzMap = new HashMap<>();
        List<JwOrgEntity> clazzList = orgService.findAll();
        for(JwOrgEntity clazz : clazzList) {
            clazzMap.put(clazz.getId(), clazz);
        }
        for(SchoolStudentImportModel model : list) {
            List<SchoolStudentEntity> dbList = this.repository.findByName(model.getName());
            boolean exists = false;
            if(dbList != null && dbList.size() > 0) {
                for(SchoolStudentEntity student : dbList) {
                    if(clazzMap.get(student.getOrgId()) != null && clazzMap.get(student.getOrgId()).getDid() != null && clazzMap.get(student.getOrgId()).getDid().equals(model.getDid())) {
                        //数据库已存在
                        student.setDid(model.getDid());
                        student.setCardNumber(model.getCardNumber());
                        student.setCid(model.getCid());
                        student.setIsDel("0");
                        student.setSex("1");
                        student.setStudentId(model.getStudentId());

                        UserEntity teacher = userService.findClazzMaster(student.getOrgId());
                        student.setMaster(teacher);
                        this.repository.save(student);
                        exists = true;
                        break;
                    }
                }
            }

            if(!exists) {
                //新增
                SchoolStudentEntity student = new SchoolStudentEntity();
                student.setDid(model.getDid());
                student.setCardNumber(model.getCardNumber());
                student.setCid(model.getCid());
                student.setIsDel("0");
                student.setSex("1");
                student.setStudentId(model.getStudentId());
                student.setName(model.getName());

                JwOrgEntity clazz = orgService.findByDid(model.getDid());
                student.setOrgId(clazz.getId());
                student.setOrgName(clazz.getName());

                UserEntity teacher = userService.findClazzMaster(student.getOrgId());
                student.setMaster(teacher);

                List<SchoolStudentEntity> studentList = new ArrayList<>();
                studentList.add(student);

                this.repository.saveAll(studentList);
            }
        }
    }

    private Specification<SchoolStudentEntity> getSpecificationByUser(List<String> clazzIdList, String clazzId, String name, String studentId){
        return new Specification<SchoolStudentEntity>() {
            @Override
            public Predicate toPredicate(Root<SchoolStudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Path<String> pathName = root.get("name");
                Path<String> pathOrgId = root.get("orgId");
                Path<String> pathStudentId = root.get("studentId");
                Path<String> pathIsDel = root.get("isDel");
                ArrayList<Predicate> list = new ArrayList<Predicate>();
                if (!StringUtils.isEmptyOrWhitespace(name)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.like(pathName, "%" + name + "%")));
                }
                if (!StringUtils.isEmptyOrWhitespace(clazzId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathOrgId, clazzId)));
                }
                if (!StringUtils.isEmptyOrWhitespace(studentId)) {
                    list.add(criteriaBuilder.and(criteriaBuilder.equal(pathStudentId, studentId)));
                }
                Expression<String> exp = root.<String>get("orgId");
                if(null!=clazzIdList && clazzIdList.size()>0){
                    list.add(exp.in(clazzIdList));
                }
                list.add(criteriaBuilder.and(criteriaBuilder.equal(pathIsDel, "0")));
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
    }


}